package gatperdut.chato.core.item.inventory;

import gatperdut.chato.constants.CSConstantsString;
import gatperdut.chato.core.ChatoServer;
import gatperdut.chato.core.interpreter.grammar.comminfo.indexedword.IndexedWord;
import gatperdut.chato.core.item.ItemController;
import gatperdut.chato.core.room.DoorController;
import gatperdut.chato.model.Chato.Item.GenericInventory;
import gatperdut.chato.model.Chato.Item.ItemTemplate;

import java.util.ArrayList;
import java.util.List;

public abstract class InventoryController {

    private final GenericInventory inventory;

    private final ChatoServer chatoServer;

    private final List<ItemController> itemControllers = new ArrayList<ItemController>();

    public InventoryController( ChatoServer chatoServer, GenericInventory inventory ) {
        this.inventory = inventory;
        this.chatoServer = chatoServer;
    }

    public GenericInventory getInventory() {
        return inventory;
    }

    public List<ItemController> getItemControllers() {
        return itemControllers;
    }

    public ItemController getItemController( IndexedWord iw ) {
        int matches = 0;

        for ( ItemController ic : getItemControllers() ) {
            if ( ic.getKeywordsController().matchesKeyword( iw.getWord() ) ) {
                matches++;
                if ( matches == iw.getIndex() ) {
                    return ic;
                }
            }
        }

        return null;
    }

    public ItemController getItemControllerMatchingTemplate( ItemTemplate it ) {
        for ( ItemController ic : getItemControllers() ) {
            if ( ic.getItem().getTemplate() == it ) {
                return ic;
            }
        }

        return null;
    }

    public void unloadItems() {
        for ( ItemController ic : getItemControllers() ) {
            if ( ic.getInventoryController() != null ) {
                ic.getInventoryController().unloadItems();
            }
            getChatoServer().getItemHandler().getItemToController().remove( ic.getItem() );
        }
        getItemControllers().clear();
    }

    public abstract String listContentsShortDescription( boolean showDrinkableContents );

    public String listContentsLongDescription() {
        StringBuilder contents = new StringBuilder( "" );
        boolean firstListed = false;
        for ( ItemController ic : getItemControllers() ) {
            if ( !firstListed ) {
                firstListed = true;
            }
            else {
                contents.append( CSConstantsString.NEWLINE );
            }
            contents.append( ic.getLongDesc() );
        }
        return contents.toString();
    }

    public void takeFromInventory( ItemController ic ) {
        ic.setContainerController( null );
        getItemControllers().remove( ic );
    }

    public ItemController findKeyForContainer( ItemController ic ) {
        for ( ItemController possibleKey : getItemControllers() ) {
            if ( ic.getLockController().unlocksWith( possibleKey ) ) {
                return possibleKey;
            }
        }
        return null;
    }

    public ItemController findKeyForDoor( DoorController dc ) {
        for ( ItemController possibleKey : getItemControllers() ) {
            if ( dc.getLockController().unlocksWith( possibleKey ) ) {
                return possibleKey;
            }
        }
        return null;
    }

    public void junkAll() {
        ItemController ic;
        while ( getNumberOfItems() > 0 ) {
            ic = getItemControllers().get( 0 );
            if ( ic.isStorage() ) {
                ic.getInventoryController().junkAll();
            }
            junk( ic );
        }
    }

    public void dumpInto( BoxInventoryController box ) {
        ItemController ic;
        while ( getNumberOfItems() > 0 ) {
            ic = getItemControllers().get( 0 );
            takeFromInventory( ic );
            box.putInInventory( ic );

        }
    }

    public int getNumberOfItems() {
        return getItemControllers().size();
    }

    public void junk( ItemController ic ) {
        if ( ic.isStorage() ) {
            ic.getInventoryController().junkAll();
        }
        takeFromInventory( ic );
        getChatoServer().getItemHandler().junkItem( ic );
    }

    public boolean isEmpty() {
        return getItemControllers().isEmpty();
    }

    public int computeWeight() {
        int accum = 0;
        for ( ItemController ic : getItemControllers() ) {
            accum += ic.computeWeight();
        }

        return accum;
    }

    public ChatoServer getChatoServer() {
        return chatoServer;
    }

}
